<!DOCTYPE html>
<html lang="zh-CN">


<head>
  <meta charset="utf-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <meta name="author" content="viggo" />
  <title>MrLiu的博客 - </title>
  <meta name="keywords" content="">
  <meta name="description" content="">
  <link rel="shortcut icon" href="/static/favicon.ico">
  <link rel="stylesheet" href="/css/github.min.css">
  <script src="/js/highlight.min.js"></script>
  
<link rel="stylesheet" href="//fonts.loli.net/css?family=Arimo:400,700,400italic.css">
<link rel="stylesheet" href="/css/fonts/linecons/css/linecons.min.css">
<link rel="stylesheet" href="/css/fonts/fontawesome/css/all.min.css">
<link rel="stylesheet" href="/css/bootstrap.min.css">
<link rel="stylesheet" href="/css/xenon-core.min.css">
<link rel="stylesheet" href="/css/xenon-components.min.css">
<link rel="stylesheet" href="/css/xenon-skins.min.css">
<link rel="stylesheet" href="/css/index.css">
<link rel="stylesheet" href="/css/nav.min.css">
<link rel="stylesheet" href="/css/md.css">

  
<script src="/js/jquery-1.11.1.min.js"></script>

  
<script src="/js/header.js"></script>

  <!-- HTML5 shim and Respond.js IE8 support of HTML5 elements and media queries -->
  <!--[if lt IE 9]>
        
<script src="/js/html5shiv.min.js"></script>

        
<script src="/js/respond.min.js"></script>

    <![endif]-->
  <script>
  hljs.configure({useBR: true});
  hljs.initHighlightingOnLoad();
  </script>
  <!-- / FB Open Graph -->
  <meta property="og:type" content="article">
  <meta property="og:url" content="https://liu-meizhou.github.io/js%E5%8E%9F%E5%9E%8B%E9%93%BE/index.html">
  <meta property="og:title" content="MrLiu的博客 - ">
  <meta property="og:description" content="">
  <meta property="og:site_name" content="MrLiu的博客 - ">
  
  <meta property="og:image" content="/images/webstack_banner_cn.png">
  
  <!-- / Twitter Cards -->
  <meta name="twitter:card" content="summary_large_image">
  <meta name="twitter:title" content="MrLiu的博客 - ">
  <meta name="twitter:description" content="">
  
  <meta name="twitter:image" content="/images/webstack_banner_cn.png">
  
<meta name="generator" content="Hexo 5.4.0"></head>

<body>
  <div class="page-container">
    <div class="sidebar-menu toggle-others fixed">
  <div class="sidebar-menu-inner">
    <header class="logo-env">
      <div class="logo">
        <a href="/index.html" class="logo-expanded">
          <img src="/images/logo@2x.png" width="100%" alt="" />
        </a>
        <a href="/index.html" class="logo-collapsed">
          <img src="/images/logo-collapsed@2x.png" width="40" alt="" />
        </a>
      </div>
      <div class="mobile-menu-toggle visible-xs">
        <a href="#" data-toggle="user-info-menu">
          <i class="linecons-cog"></i>
        </a>
        <a href="#" data-toggle="mobile-menu">
          <i class="fas fa-bars"></i>
        </a>
      </div>
    </header>
    <ul id="main-menu" class="main-menu">
      

      
        <li><a href="#为什么要用webpack" class="fas fa-angle-down" style="cursor: pointer; padding-left: 0em" title="为什么要用webpack"><i class="far fa-star"></i><span class="title">为什么要用webpack</span></a><ul><li><a href="#如何在web中使用javascipt的" class="fas fa-angle-down" style="cursor: pointer; padding-left: 1em" title="如何在web中使用javascipt的"><i class="far fa-star"></i><span class="title">如何在web中使用javascipt的</span></a><ul><li><a href="#没有webpack" class="smooth" style="padding-left: 2em" title="没有webpack"><i class="far fa-star"></i><span class="title">没有webpack</span></a></li><li><a href="#出现了nodejs" class="smooth" style="padding-left: 2em" title="出现了nodejs"><i class="far fa-star"></i><span class="title">出现了nodejs</span></a></li><li><a href="#出现了webpack" class="smooth" style="padding-left: 2em" title="出现了webpack"><i class="far fa-star"></i><span class="title">出现了webpack</span></a></li></ul></li></ul></li><li><a href="#如何使用webpack" class="fas fa-angle-down" style="cursor: pointer; padding-left: 0em" title="如何使用webpack"><i class="far fa-star"></i><span class="title">如何使用webpack</span></a><ul><li><a href="#简单使用" class="smooth" style="padding-left: 1em" title="简单使用"><i class="far fa-star"></i><span class="title">简单使用</span></a></li><li><a href="#资源管理" class="smooth" style="padding-left: 1em" title="资源管理"><i class="far fa-star"></i><span class="title">资源管理</span></a></li><li><a href="#管理输出" class="smooth" style="padding-left: 1em" title="管理输出"><i class="far fa-star"></i><span class="title">管理输出</span></a></li><li><a href="#开发环境" class="smooth" style="padding-left: 1em" title="开发环境"><i class="far fa-star"></i><span class="title">开发环境</span></a></li><li><a href="#代码分离" class="fas fa-angle-down" style="cursor: pointer; padding-left: 1em" title="代码分离"><i class="far fa-star"></i><span class="title">代码分离</span></a><ul><li><a href="#方法" class="fas fa-angle-down" style="cursor: pointer; padding-left: 2em" title="方法"><i class="far fa-star"></i><span class="title">方法</span></a><ul><li><a href="#入口起点" class="smooth" style="padding-left: 3em" title="入口起点"><i class="far fa-star"></i><span class="title">入口起点</span></a></li><li><a href="#防止重复" class="smooth" style="padding-left: 3em" title="防止重复"><i class="far fa-star"></i><span class="title">防止重复</span></a></li><li><a href="#动态导入" class="smooth" style="padding-left: 3em" title="动态导入"><i class="far fa-star"></i><span class="title">动态导入</span></a></li></ul></li><li><a href="#预取" class="fas fa-angle-down" style="cursor: pointer; padding-left: 2em" title="预取"><i class="far fa-star"></i><span class="title">预取</span></a><ul><li><a href="#prefetch预获取" class="smooth" style="padding-left: 3em" title="prefetch预获取"><i class="far fa-star"></i><span class="title">prefetch预获取</span></a></li><li><a href="#preload预加载" class="smooth" style="padding-left: 3em" title="preload预加载"><i class="far fa-star"></i><span class="title">preload预加载</span></a></li></ul></li><li><a href="#bundle分析" class="smooth" style="padding-left: 2em" title="bundle分析"><i class="far fa-star"></i><span class="title">bundle分析</span></a></li></ul></li><li><a href="#缓存" class="fas fa-angle-down" style="cursor: pointer; padding-left: 1em" title="缓存"><i class="far fa-star"></i><span class="title">缓存</span></a><ul><li><a href="#介绍" class="smooth" style="padding-left: 2em" title="介绍"><i class="far fa-star"></i><span class="title">介绍</span></a></li></ul></li><li><a href="#打包library" class="fas fa-angle-down" style="cursor: pointer; padding-left: 1em" title="打包library"><i class="far fa-star"></i><span class="title">打包library</span></a><ul><li><a href="#代码" class="smooth" style="padding-left: 2em" title="代码"><i class="far fa-star"></i><span class="title">代码</span></a></li><li><a href="#优化大小" class="smooth" style="padding-left: 2em" title="优化大小"><i class="far fa-star"></i><span class="title">优化大小</span></a></li><li><a href="#按需引入库" class="smooth" style="padding-left: 2em" title="按需引入库"><i class="far fa-star"></i><span class="title">按需引入库</span></a></li></ul></li></ul></li>
      

      
      <li class="submit-tag">
        <a href="/author">
          <i class="far fa-heart"></i>
          <span class="tooltip-blue">关于作者</span>
        </a>
      </li>
      
      
      <li>
        <a href="javascript:void(0)">
          <i class="fas fa-eye"></i>
          <span id="busuanzi_container_site_pv">本站总访问量<span id="busuanzi_value_site_pv"></span></span>
        </a>
      </li>
      <li>
        <a href="javascript:void(0)">
          <i class="fas fa-users"></i>
          <span id="busuanzi_container_site_uv">本站总访客数<span id="busuanzi_value_site_uv"></span></span>
        </a>
      </li>
      
    </ul>
  </div>
  <div class="e-resize"></div>
</div>

    <div class="main-content">
      <nav class="navbar user-info-navbar" role="navigation">
        <ul class="user-info-menu left-links list-inline list-unstyled">
          <li class="hidden-sm hidden-xs hover-line">
            <a href="#" data-toggle="sidebar">
              <i class="fas fa-bars"></i>
            </a>
          </li>
          <li class="dropdown hover-line language-switcher">
            <a href="/index.html" class="dropdown-toggle" data-toggle="dropdown">
              <img src="/images/flags/flag-cn.png" alt="flag-cn" /> Chinese
            </a>
            <ul class="dropdown-menu languages">
              <li class="active">
                <a href="/index.html">
                  <img src="/images/flags/flag-cn.png" alt="flag-cn" alt="flag-cn" /> Chinese
                </a>
              </li>
            </ul>
          </li>
          <li class="switch-mode hover-line" onclick="switchNightMode()">
            <a href="#">
              <svg t="1593061068148" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1681" width="16" height="16">
                <path d="M582.4 326.4c-140.8 0-256 115.2-256 256s115.2 256 256 256 256-115.2 256-256-115.2-256-256-256z m0 448c-70.4 0-131.2-36.8-164.8-92.8 12.8 3.2 27.2 4.8 40 4.8 121.6 0 219.2-99.2 219.2-219.2 0-17.6-1.6-35.2-6.4-52.8 60.8 32 102.4 96 102.4 169.6 1.6 104-84.8 190.4-190.4 190.4zM582.4 262.4c17.6 0 32-14.4 32-32v-128c0-17.6-14.4-32-32-32s-32 14.4-32 32v128c0 17.6 14.4 32 32 32zM262.4 582.4c0-17.6-14.4-32-32-32h-128c-17.6 0-32 14.4-32 32s14.4 32 32 32h128c17.6 0 32-14.4 32-32zM310.4 356.8c6.4 6.4 14.4 9.6 22.4 9.6 8 0 16-3.2 22.4-9.6 12.8-12.8 12.8-32 0-44.8l-91.2-91.2c-12.8-12.8-32-12.8-44.8 0-12.8 12.8-12.8 32 0 44.8l91.2 91.2zM944 220.8c-12.8-12.8-32-12.8-44.8 0l-91.2 91.2c-12.8 12.8-12.8 32 0 44.8 6.4 6.4 14.4 9.6 22.4 9.6 8 0 16-3.2 22.4-9.6l91.2-91.2c12.8-12.8 12.8-33.6 0-44.8zM310.4 808l-91.2 91.2c-12.8 12.8-12.8 32 0 44.8 6.4 6.4 14.4 9.6 22.4 9.6 8 0 16-3.2 22.4-9.6l91.2-91.2c12.8-12.8 12.8-32 0-44.8-11.2-11.2-32-11.2-44.8 0z" p-id="1682" fill="#707070"></path>
              </svg>
            </a>
          </li>
        </ul>
        
        <a target="_blank" rel="noopener" href="https://github.com/liu-meizhou/liu-meizhou.github.io" class="github-corner" aria-label="View source on GitHub"><svg width="80" height="80" viewBox="0 0 250 250" style="fill:#151513; color:#fff; position: absolute; top: 0; border: 0; right: 0;" aria-hidden="true"><path d="M0,0 L115,115 L130,115 L142,142 L250,250 L250,0 Z"></path><path d="M128.3,109.0 C113.8,99.7 119.0,89.6 119.0,89.6 C122.0,82.7 120.5,78.6 120.5,78.6 C119.2,72.0 123.4,76.3 123.4,76.3 C127.3,80.9 125.5,87.3 125.5,87.3 C122.9,97.6 130.6,101.9 134.4,103.2" fill="currentColor" style="transform-origin: 130px 106px;" class="octo-arm"></path><path d="M115.0,115.0 C114.9,115.1 118.7,116.5 119.8,115.4 L133.7,101.6 C136.9,99.2 139.9,98.4 142.2,98.6 C133.8,88.0 127.5,74.4 143.8,58.0 C148.5,53.4 154.0,51.2 159.7,51.0 C160.3,49.4 163.2,43.6 171.4,40.1 C171.4,40.1 176.1,42.5 178.8,56.2 C183.1,58.6 187.2,61.8 190.9,65.4 C194.5,69.0 197.7,73.2 200.1,77.6 C213.8,80.2 216.3,84.9 216.3,84.9 C212.7,93.1 206.9,96.0 205.4,96.6 C205.1,102.4 203.0,107.8 198.3,112.5 C181.9,128.9 168.3,122.5 157.7,114.1 C157.9,116.9 156.7,120.9 152.7,124.9 L141.0,136.5 C139.8,137.7 141.6,141.9 141.8,141.8 Z" fill="currentColor" class="octo-body"></path></svg></a><style>.github-corner:hover .octo-arm{animation:octocat-wave 560ms ease-in-out}@keyframes octocat-wave{0%,100%{transform:rotate(0)}20%,60%{transform:rotate(-25deg)}40%,80%{transform:rotate(10deg)}}@media (max-width:500px){.github-corner:hover .octo-arm{animation:none}.github-corner .octo-arm{animation:octocat-wave 560ms ease-in-out}}</style>
        
      </nav>
      
<h1 id="为什么要用webpack"><a href="#为什么要用webpack" class="headerlink" title="为什么要用webpack"></a>为什么要用webpack</h1><h2 id="如何在web中使用javascipt的"><a href="#如何在web中使用javascipt的" class="headerlink" title="如何在web中使用javascipt的"></a>如何在web中使用javascipt的</h2><h3 id="没有webpack"><a href="#没有webpack" class="headerlink" title="没有webpack"></a>没有webpack</h3><ul>
<li><p>html中引用js文件</p>
<figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs html"><span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">src</span>=<span class="hljs-string">&quot;xxx.js&quot;</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span><br><span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">src</span>=<span class="hljs-string">&quot;xxx2.js&quot;</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span><br>...<br></code></pre></td></tr></table></figure>

<ul>
<li>维护问题：扩展不方便</li>
<li>网络问题：脚本过多，加载脚本也会偏慢</li>
</ul>
</li>
<li><p>改进：脚本过多加载慢问题</p>
<figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs html"><span class="hljs-comment">&lt;!-- 把所有脚本压缩到一个js文件中 --&gt;</span><br><span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">src</span>=<span class="hljs-string">&quot;app.min.js&quot;</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span><br></code></pre></td></tr></table></figure>

<ul>
<li>维护问题：扩展不方便、可读性差、作用域混乱</li>
</ul>
</li>
<li><p>改进：解决作用域混乱，使用<code>IIFE: Immediately invoked function expressions 立即执行函数表达式</code></p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-comment">// 第一个圆括号包含了整个匿名函数，这个函数拥有独立的词法作用域</span><br>(<span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>&#123;<br>    <span class="hljs-keyword">var</span> name = <span class="hljs-string">&quot;IIFE&quot;</span>;<br>&#125;)();<br><br><span class="hljs-comment">// 外部无法访问</span><br><span class="hljs-built_in">console</span>.log(name); <span class="hljs-comment">// 抛出错误: name is not defined</span><br><br>(<span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>&#123;<br>    <span class="hljs-keyword">var</span> name = <span class="hljs-string">&quot;IIFE2&quot;</span><br>&#125;)();<br></code></pre></td></tr></table></figure>

<ul>
<li>维护问题：扩展不方便、可读性差</li>
</ul>
</li>
</ul>
<h3 id="出现了nodejs"><a href="#出现了nodejs" class="headerlink" title="出现了nodejs"></a>出现了nodejs</h3><p><strong>nodejs</strong>：一个javascript运行时环境，可以在浏览器之外的计算机和服务器中使用。webpack运行在nodejs中。</p>
<ul>
<li><p>改进：作用域混乱、扩展不方便、可读性差，使用<code>CommonJS的require</code>机制</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-comment">// 模块化引入</span><br><span class="hljs-comment">// 解决作用域问题,所有变量都在xxxModel对象内</span><br><span class="hljs-keyword">var</span> xxxModel = <span class="hljs-built_in">require</span>(<span class="hljs-string">&#x27;xxx&#x27;</span>)<br><span class="hljs-comment">// 项目中引入echarts</span><br><span class="hljs-keyword">var</span> echarts = <span class="hljs-built_in">require</span>(<span class="hljs-string">&#x27;echarts/lib/echarts&#x27;</span>)<br></code></pre></td></tr></table></figure>

<ul>
<li>发布问题：CommonJS没有浏览器支持</li>
</ul>
</li>
</ul>
<h3 id="出现了webpack"><a href="#出现了webpack" class="headerlink" title="出现了webpack"></a>出现了webpack</h3><p><strong>webpack</strong>：打包工具，打包JavaScript应用程序（支持ESM和COmmonJS），可以扩展为支持许多不同的资产（images、fonts、stylesheets）</p>
<p>关心性能和加载时间：异步加载<code>chunk</code>和预取等</p>
<h1 id="如何使用webpack"><a href="#如何使用webpack" class="headerlink" title="如何使用webpack"></a>如何使用webpack</h1><h2 id="简单使用"><a href="#简单使用" class="headerlink" title="简单使用"></a>简单使用</h2><ul>
<li><p>安装：<code>npm install webpack webpack-cli --save-dev</code></p>
</li>
<li><p>编写配置文件：<code>默认文件名 webpack-config.js</code></p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-keyword">const</span> path = <span class="hljs-built_in">require</span>(<span class="hljs-string">&#x27;path&#x27;</span>);<br><br><span class="hljs-built_in">module</span>.exports = &#123;<br>    <span class="hljs-comment">// ... 详细看webpack配置</span><br>&#125;<br></code></pre></td></tr></table></figure></li>
<li><p>打包：下面两个命令都是运行本地node_modules的webpack命令</p>
<p><code>npx webpack --config webpack.config.js</code></p>
<p><code>npm run build</code></p>
<p>配置package.json:</p>
<figure class="highlight json"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><code class="hljs json">&#123;<br>    <span class="hljs-attr">&quot;scripts&quot;</span>: &#123;<br>        <span class="hljs-attr">&quot;build&quot;</span>: <span class="hljs-string">&quot;webpack&quot;</span><br>    &#125;<br>&#125;<br></code></pre></td></tr></table></figure></li>
</ul>
<h2 id="资源管理"><a href="#资源管理" class="headerlink" title="资源管理"></a>资源管理</h2><p>webpack从配置文件中指定的入口<code>entry</code>开始构建一个<em>关系依赖图</em>，这个依赖图记录了每个模块所依赖的资源<code>js库、css、字体、图片等</code>，这样可以避免打包无用资源</p>
<p>当JS资源需要保持状态一致性或者实例共享时，需要注意<a target="_blank" rel="noopener" href="https://bundlers.tooling.report/code-splitting/multi-entry/">这个问题</a></p>
<p>解决这个问题：<code>往往一个页面多个入口需要面临这个问题</code>·</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-built_in">module</span>.exports = &#123;<br>    optimization: &#123;<br>        runtimeChunk: <span class="hljs-string">&quot;single&quot;</span>, <span class="hljs-comment">// 会阻止创建同一模块两个实例</span><br>    &#125;<br>&#125;<br></code></pre></td></tr></table></figure>

<h2 id="管理输出"><a href="#管理输出" class="headerlink" title="管理输出"></a>管理输出</h2><p>了解<code>HtmlWebpackPlugin</code>：根据一些数据生成html页面</p>
<h2 id="开发环境"><a href="#开发环境" class="headerlink" title="开发环境"></a>开发环境</h2><ul>
<li><p>配置<code>source map</code>：定位到每一个错误的具体文件具体行</p>
</li>
<li><p>配置热更新：代码改变后自动编译代码</p>
<ul>
<li><p>webpack‘s Watch Mode：观察者模式 <code>webpack --watch</code></p>
</li>
<li><p>webpack-dev-server：dev服务<code>一般用这个</code> <code>webpack serve --open</code></p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-built_in">module</span>.exports = &#123;<br>    devServer: &#123;<br>        <span class="hljs-comment">// ...</span><br>    &#125;<br>&#125;<br></code></pre></td></tr></table></figure></li>
<li><p>webpack-dev-middleware：封装器</p>
</li>
</ul>
</li>
</ul>
<h2 id="代码分离"><a href="#代码分离" class="headerlink" title="代码分离"></a>代码分离</h2><p><strong>高级内容</strong>，此模块是将代码分离到不同的bundle中，这样浏览器就可以<code>按需加载</code>、<code>并行加载</code>，可以控制资源加载优先级，使用合理可以大幅度影响页面响应时间<code>从请求到显示界面</code></p>
<h3 id="方法"><a href="#方法" class="headerlink" title="方法"></a>方法</h3><h4 id="入口起点"><a href="#入口起点" class="headerlink" title="入口起点"></a>入口起点</h4><ul>
<li><p>使用<code>entry</code>配置手动分离代码</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-built_in">module</span>.exports = &#123;<br>    <span class="hljs-comment">// 配置两个入口，当访问/index进入html入口</span><br>    <span class="hljs-comment">// 访问/other进入other入口</span><br>    entry: &#123;<br>        index: <span class="hljs-string">&#x27;xxx.js&#x27;</span>,<br>        other: <span class="hljs-string">&#x27;xxx.js&#x27;</span>,<br>    &#125;<br>&#125;<br></code></pre></td></tr></table></figure>

<ul>
<li><p>重复引入问题：不同入口的chunk中相同的依赖会被重复引入</p>
</li>
<li><p>手动配置不够灵活，师兄的代码采用<code>path</code>去遍历文件系统生成entry解决灵活性</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-keyword">const</span> glob = <span class="hljs-built_in">require</span>(<span class="hljs-string">&#x27;glob&#x27;</span>)<br><span class="hljs-keyword">const</span> globPath = <span class="hljs-string">&#x27;./src/pages/**/main.js&#x27;</span><br><span class="hljs-keyword">const</span> entries = &#123;&#125;<br>glob.sync(globPath).forEach(<span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">entry</span>) </span>&#123;<br>    <span class="hljs-keyword">const</span> paths = entry.split(<span class="hljs-string">&#x27;/&#x27;</span>);<br>    <span class="hljs-keyword">const</span> path = paths.slice(<span class="hljs-number">3</span>, -<span class="hljs-number">1</span>).json(<span class="hljs-string">&#x27;/&#x27;</span>);<br>    <span class="hljs-comment">// 动态生成chunk入口</span><br>    entries[path] = &#123;<br>        entry: <span class="hljs-string">&#x27;src/pages/&#x27;</span> + path + <span class="hljs-string">&#x27;/main.js&#x27;</span>,<br>        template: <span class="hljs-string">&#x27;src/pages/&#x27;</span> + path + <span class="hljs-string">&#x27;/index.html&#x27;</span>,<br>        filename: path + <span class="hljs-string">&#x27;.html&#x27;</span>,<br>        title: <span class="hljs-built_in">require</span>(<span class="hljs-string">&#x27;./src/pages/&#x27;</span> + path + <span class="hljs-string">&#x27;/config.js&#x27;</span>).title,<br>    &#125;<br>&#125;)<br></code></pre></td></tr></table></figure></li>
</ul>
</li>
</ul>
<h4 id="防止重复"><a href="#防止重复" class="headerlink" title="防止重复"></a>防止重复</h4><ul>
<li>使用<code>Entry dependencies或SplitChunksPlugin</code>去重和分离<code>chunk</code><ul>
<li><code>Entry dependencies</code>：查看webpack配置中的<code>Dependencies</code>，配置多个chunk共享相同的依赖</li>
<li><code>SplitChunksPlugin</code>：查看webpack配置中的<code>optimization.splitChunks</code></li>
</ul>
</li>
</ul>
<h4 id="动态导入"><a href="#动态导入" class="headerlink" title="动态导入"></a>动态导入</h4><ul>
<li><p>通过模块的内联函数调用来分离代码</p>
<ul>
<li><p>使用 <code>import(‘xxx’)</code>导入模块，将访问<code>promise</code>对象，实现异步动态导入</p>
<p>注：IE 11 需要使用polyfill库来替换promis (IE 11 不支持)</p>
</li>
</ul>
</li>
</ul>
<h3 id="预取"><a href="#预取" class="headerlink" title="预取"></a>预取</h3><h4 id="prefetch预获取"><a href="#prefetch预获取" class="headerlink" title="prefetch预获取"></a>prefetch预获取</h4><p>将来某些导航下可能需要的资源</p>
<p>在登录界面中的点击登录按钮，配置这个js预获取加载</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-keyword">import</span>(<span class="hljs-comment">/* webpackPrefetch: true */</span> <span class="hljs-string">&#x27;./xxx.js&#x27;</span>);<br></code></pre></td></tr></table></figure>

<p>上面的代码会生成为</p>
<figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs html"><span class="hljs-tag">&lt;<span class="hljs-name">link</span> <span class="hljs-attr">rel</span>=<span class="hljs-string">&quot;prefetch&quot;</span> <span class="hljs-attr">href</span>=<span class="hljs-string">&quot;./xxx.js&quot;</span> /&gt;</span><br></code></pre></td></tr></table></figure>

<p>放在页面头部</p>
<p><code>只要父chunk完成加载，webpack就会添加prefetch hint(预取提示)，在闲置时间预取该js文件</code></p>
<h4 id="preload预加载"><a href="#preload预加载" class="headerlink" title="preload预加载"></a>preload预加载</h4><p>当前导航下可能需要的资源</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-keyword">import</span>(<span class="hljs-comment">/* webpackPreload: true */</span> <span class="hljs-string">&#x27;./xxx.js&#x27;</span>);<br></code></pre></td></tr></table></figure>

<figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs html"><span class="hljs-tag">&lt;<span class="hljs-name">link</span> <span class="hljs-attr">rel</span>=<span class="hljs-string">&quot;preload&quot;</span> <span class="hljs-attr">href</span>=<span class="hljs-string">&quot;./xxx.js&quot;</span>&gt;</span><br></code></pre></td></tr></table></figure>

<p><code>在父chunk加载的同时，并行方式开始加载js文件，不正确的使用会又性能损失</code></p>
<h3 id="bundle分析"><a href="#bundle分析" class="headerlink" title="bundle分析"></a>bundle分析</h3><p> <a target="_blank" rel="noopener" href="https://github.com/webpack/analyse">官方分析工具</a></p>
<p>社区支持：</p>
<ul>
<li><a target="_blank" rel="noopener" href="https://alexkuz.github.io/webpack-chart/">webpack-chart</a>: webpack stats 可交互饼图。</li>
<li><a target="_blank" rel="noopener" href="https://chrisbateman.github.io/webpack-visualizer/">webpack-visualizer</a>: 可视化并分析你的 bundle，检查哪些模块占用空间，哪些可能是重复使用的。</li>
<li><a target="_blank" rel="noopener" href="https://github.com/webpack-contrib/webpack-bundle-analyzer">webpack-bundle-analyzer</a>：一个 plugin 和 CLI 工具，它将 bundle 内容展示为一个便捷的、交互式、可缩放的树状图形式。</li>
<li><a target="_blank" rel="noopener" href="https://webpack.jakoblind.no/optimize">webpack bundle optimize helper</a>：这个工具会分析你的 bundle，并提供可操作的改进措施，以减少 bundle 的大小。</li>
<li><a target="_blank" rel="noopener" href="https://github.com/bundle-stats/bundle-stats">bundle-stats</a>：生成一个 bundle 报告（bundle 大小、资源、模块），并比较不同构建之间的结果。</li>
</ul>
<h2 id="缓存"><a href="#缓存" class="headerlink" title="缓存"></a>缓存</h2><h3 id="介绍"><a href="#介绍" class="headerlink" title="介绍"></a>介绍</h3><p><strong>高级内容</strong>：通过webpack的配置，使生成的文件能够被<em>客户端缓存</em>，而在文件内容变化后，能够请求到新的文件（是采用文件名查看文件是否更改，而文件名是采用contenthash生成）</p>
<p><code>看到这里我想起了ETag</code></p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-comment">// 配置输出文件名为contenthash</span><br><span class="hljs-built_in">module</span>.exports = &#123;<br>    output: &#123;<br>        filename: <span class="hljs-string">&#x27;[name].[contenthash].js&#x27;</span><br>    &#125;<br>&#125;<br></code></pre></td></tr></table></figure>

<p>查看webpack配置中的<code>optimization.runtimeChunk和optimization.splitChunks.cacheGroups</code></p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-comment">// 提取引导模板</span><br><span class="hljs-built_in">module</span>.exports = &#123;<br>    optimization: &#123;<br>        moduleIds: <span class="hljs-string">&#x27;deterministic&#x27;</span>, <span class="hljs-comment">// 第三方依赖的引入模块号固定</span><br>        runtimeChunk: <span class="hljs-string">&#x27;single&#x27;</span>, <span class="hljs-comment">// 将运行时的chunk提取出来</span><br>        solitChunks: &#123; <span class="hljs-comment">// 将node_modules中的依赖提取出来</span><br>            cacheGroups: &#123;<br>                vendor: &#123;<br>                    test: <span class="hljs-regexp">/[\\/]node_modules[\\/]/</span>,<br>                    name: <span class="hljs-string">&#x27;vendors&#x27;</span>,<br>                    chunks: <span class="hljs-string">&#x27;all&#x27;</span>,<br>                &#125;<br>            &#125;<br>        &#125;<br>    &#125;<br>&#125;<br></code></pre></td></tr></table></figure>

<ul>
<li>node_modules依赖很好被修改，会命中缓存，而且分离第三方模块之后，剩下文件会变得非常小</li>
</ul>
<h2 id="打包library"><a href="#打包library" class="headerlink" title="打包library"></a>打包library</h2><h3 id="代码"><a href="#代码" class="headerlink" title="代码"></a>代码</h3><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-comment">// 打包完为普通js，可运行在浏览器环境上</span><br><span class="hljs-comment">// 浏览器引入 &lt;script src=&quot;webpackNumbers.js&quot;&gt;&lt;/script&gt;</span><br><span class="hljs-built_in">module</span>.exports = &#123;<br>    output: &#123;<br>        library: <span class="hljs-string">&quot;webpackNumbers&quot;</span>,<br>    &#125;<br>&#125;<br><br><span class="hljs-comment">// 让它兼容不同的运行环境CommonJS、AMD、浏览器</span><br><span class="hljs-comment">// COmmonJS: const webpackNumbers = require(&#x27;webpack-numbers&#x27;)</span><br><span class="hljs-comment">// AMD: require([&#x27;webpackNumbers&#x27;], function (webpackNumber) &#123; ... &#125;)</span><br><span class="hljs-built_in">module</span>.exports = &#123;<br>    output: &#123;<br>        library: &#123;<br>            name: <span class="hljs-string">&#x27;webpackNumber&#x27;</span>,<br>            type: <span class="hljs-string">&#x27;umd&#x27;</span>,<br>        &#125;<br>    &#125;<br>&#125;<br></code></pre></td></tr></table></figure>

<h3 id="优化大小"><a href="#优化大小" class="headerlink" title="优化大小"></a>优化大小</h3><p>第三方库打包完成后，它里面的依赖也会被打包进来，如果该依赖和项目依赖冲突，那是没必要打包进来的，把那些易冲突的库放在consumer环境<code>用户环境</code>，比如ladash库</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-built_in">module</span>.exports = &#123;<br>    externals: &#123; <span class="hljs-comment">// 指定外部的资源</span><br>    	lodash: &#123;<br>            commonjs: <span class="hljs-string">&#x27;lodash&#x27;</span>,<br>            commonjs2: <span class="hljs-string">&#x27;lodash&#x27;</span>,<br>            amd: <span class="hljs-string">&#x27;lodash&#x27;</span>,<br>            root: <span class="hljs-string">&#x27;_&#x27;</span>,<br>        &#125;<br>	&#125;<br>&#125;<br></code></pre></td></tr></table></figure>

<h3 id="按需引入库"><a href="#按需引入库" class="headerlink" title="按需引入库"></a>按需引入库</h3><p>上面实现的库会直接引入库的所有文件，实现一个按需引入的库</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-comment">// 你在使用库</span><br><span class="hljs-keyword">import</span> A <span class="hljs-keyword">from</span> <span class="hljs-string">&#x27;library/one&#x27;</span><br><span class="hljs-keyword">import</span> B <span class="hljs-keyword">from</span> <span class="hljs-string">&#x27;library/two&#x27;</span><br><br><span class="hljs-comment">// 实现</span><br><span class="hljs-built_in">module</span>.exports = &#123;<br>    externals: [  <span class="hljs-comment">// 将你使用的库定义为外部库(用户环境的库)</span><br>        <span class="hljs-string">&#x27;library/one&#x27;</span>,<br>        <span class="hljs-string">&#x27;library/two&#x27;</span>,<br>        <span class="hljs-comment">// 匹配library开头的所有依赖</span><br>        /^library\/.+$/,<br>    ]<br>&#125;<br><br></code></pre></td></tr></table></figure>





















    </div>
  </div>
  <div class="go-up">
  <a href="#" rel="go-top">
    <i class="fas fa-angle-up"></i>
  </a>
</div>

<script src="/js/bootstrap.min.js"></script>
<script src="/js/TweenMax.min.js"></script>
<script src="/js/resizeable.min.js"></script>
<script src="/js/joinable.js"></script>
<script src="/js/xenon-api.min.js"></script>
<script src="/js/xenon-toggles.min.js"></script>
<script src="/js/xenon-custom.min.js"></script>


<script async src="https://busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js"></script>



<script src="/js/lozad.min.js"></script>


</body>

<script src="/js/footer.js"></script>

</html>
